<?php declare(strict_types=1);
/**
 * @author      xianganyall <xianganyall@gmail.com>
 * @copyright   2023-2025 owner
 **/

namespace Srv\Libs\Frame;

use Srv\Libs\Common\CommJson;
use Srv\Libs\ConfModel\RouteConf;
use Srv\Libs\Tools\Http;

final class EnvData
{
    private static array $_get                      = [];           // Request GET
    private static array $_post                     = [];           // Request POST
    private static array $_cookie                   = [];           // Request COOKIE
    private static array $_env                      = [];           // Request ENV
    private static array $_session                  = [];           // Request SESSION
    private static array $_files                    = [];           // Request FILES
    private static array $_server                   = [];           // Request SERVER
    private static array $_header                   = [];           // Request HEADER
    private static string $_rawContent              = '';           // Request rawContent
    private static int $_rawType                    = 1;            // Request Type[1-text,2-binary]
    private static string $rootPath                 = '';           // Request rootPath
    public const KEY_SERVER                         = 1;            // SERVER
    public const KEY_HEADER                         = 2;            // HEADER
    public const KEY_COOKIE                         = 4;            // COOKIE
    public const KEY_POST                           = 8;            // POST
    public const KEY_GET                            = 16;           // GET

    /**
     * @param array $get
     * @param array $post
     * @param array $cookie
     * @param array $env
     * @param array $session
     * @param array $files
     * @param array $server
     * @param array $header
     * @param string $rawContent
     * @param int $rawType
     * @return void
     * init
     */
    final public static function init(array $get = [], array $post = [], array $cookie = [], array $env = [], array $session = [], array $files = [], array $server = [], array $header = [], string $rawContent = '', int $rawType = 1):void
    {
        self::$_get             = $get;
        self::$_post            = $post;
        self::$_cookie          = $cookie;
        self::$_server          = $server;
        self::$_header          = $header;
        self::$_env             = $env;
        self::$_session         = $session;
        self::$_files           = $files;
        self::$_rawContent      = $rawContent;
        self::$_rawType         = in_array($rawType, [1, 2], true) ? $rawType : 1;
        self::$rootPath         = '';
        $_GET                   = [];
        $_POST                  = [];
        $_REQUEST               = [];
        $_COOKIE                = [];
        $_ENV                   = [];
        $_SESSION               = [];
        $_FILES                 = [];
        $_SERVER                = [];
    }

    /**
     * @param string $envStr
     * @return bool
     * initFrom
     */
    final public static function initFrom(string $envStr):bool
    {
        $envData                = CommJson::decodeArray($envStr);
        if(!isset($envData[4]) || !isset($envData[3]) || !isset($envData[2]) || !isset($envData[1]) || !isset($envData[0]) || !is_array($envData[4]) || !is_array($envData[3]) || !is_array($envData[2]) || !is_array($envData[1]) || !is_array($envData[0])) return false;
        self::$_get             = $envData[0];
        self::$_post            = $envData[1];
        self::$_cookie          = $envData[2];
        self::$_server          = $envData[3];
        self::$_header          = $envData[4];
        self::$_env             = [];
        self::$_session         = [];
        self::$_files           = [];
        self::$_rawContent      = '';
        self::$_rawType         = 1;
        $_GET                   = [];
        $_POST                  = [];
        $_REQUEST               = [];
        $_COOKIE                = [];
        $_ENV                   = [];
        $_SESSION               = [];
        $_FILES                 = [];
        $_SERVER                = [];
        return true;
    }

    /**
     * @return string
     * toSaveSocksStr
     */
    final public static function toSaveSocksStr():string
    {
        return CommJson::encodeArray([self::$_get, self::$_post, self::$_cookie, self::$_server, self::$_header]);
    }

    /**
     * @param array $data
     * @return void
     * setDataToGet
     */
    final public static function setDataToGet(array $data):void
    {
        self::$_get             = $data;
    }

    /**
     * @return array
     * getDataByGet
     */
    final public static function getDataByGet():array
    {
        return self::$_get;
    }

    /**
     * @param string $itemName
     * @return bool
     * isDataByGetItem
     */
    final public static function isDataByGetItem(string $itemName):bool
    {
        return isset(self::$_get[$itemName]);
    }

    /**
     * @param string $itemName
     * @param $value
     * @return void
     * setDataToGetItem
     */
    final public static function setDataToGetItem(string $itemName, $value):void
    {
        self::$_get[$itemName]      = $value;
    }

    /**
     * @param string $itemName
     * @return mixed|null
     * getDataByGetItem
     */
    final public static function getDataByGetItem(string $itemName)
    {
        return self::$_get[$itemName]??null;
    }

    /**
     * @param array $data
     * @return void
     * setDataToPost
     */
    final public static function setDataToPost(array $data):void
    {
        self::$_post            = $data;
    }

    /**
     * @return array
     * getDataByPost
     */
    final public static function getDataByPost():array
    {
        return self::$_post;
    }

    /**
     * @param string $itemName
     * @return bool
     * isDataByPostItem
     */
    final public static function isDataByPostItem(string $itemName):bool
    {
        return isset(self::$_post[$itemName]);
    }

    /**
     * @param string $itemName
     * @param $value
     * @return void
     * setDataToPostItem
     */
    final public static function setDataToPostItem(string $itemName, $value):void
    {
        self::$_post[$itemName]     = $value;
    }

    /**
     * @param string $itemName
     * @return mixed|null
     * getDataByPostItem
     */
    final public static function getDataByPostItem(string $itemName)
    {
        return self::$_post[$itemName]??null;
    }

    /**
     * @param array $data
     * @return void
     * setDataToCookie
     */
    final public static function setDataToCookie(array $data):void
    {
        self::$_cookie          = $data;
    }

    /**
     * @return array
     * getDataByCookie
     */
    final public static function getDataByCookie():array
    {
        return self::$_cookie;
    }

    /**
     * @param string $itemName
     * @return bool
     * isDataByCookieItem
     */
    final public static function isDataByCookieItem(string $itemName):bool
    {
        return isset(self::$_cookie[$itemName]);
    }

    /**
     * @param string $itemName
     * @param $value
     * @return void
     * setDataToCookieItem
     */
    final public static function setDataToCookieItem(string $itemName, $value):void
    {
        self::$_cookie[$itemName]   = $value;
    }

    /**
     * @param string $itemName
     * @return mixed|null
     * getDataByCookieItem
     */
    final public static function getDataByCookieItem(string $itemName)
    {
        return self::$_cookie[$itemName]??null;
    }

    /**
     * @param array $data
     * @return void
     * setDataToEnv
     */
    final public static function setDataToEnv(array $data):void
    {
        self::$_env                 = $data;
    }

    /**
     * @return array
     * getDataByEnv
     */
    final public static function getDataByEnv():array
    {
        return self::$_env;
    }

    /**
     * @param string $itemName
     * @return bool
     * isDataByEnvItem
     */
    final public static function isDataByEnvItem(string $itemName):bool
    {
        return isset(self::$_env[$itemName]);
    }

    /**
     * @param string $itemName
     * @param $value
     * @return void
     * setDataToEnvItem
     */
    final public static function setDataToEnvItem(string $itemName, $value):void
    {
        self::$_env[$itemName]      = $value;
    }

    /**
     * @param string $itemName
     * @return mixed|null
     * getDataByEnvItem
     */
    final public static function getDataByEnvItem(string $itemName)
    {
        return self::$_env[$itemName]??null;
    }

    /**
     * @param array $data
     * @return void
     * setDataToSession
     */
    final public static function setDataToSession(array $data):void
    {
        self::$_session             = $data;
    }

    /**
     * @return array
     * getDataBySession
     */
    final public static function getDataBySession():array
    {
        return self::$_session;
    }

    /**
     * @param string $itemName
     * @return bool
     * isDataBySessionItem
     */
    final public static function isDataBySessionItem(string $itemName):bool
    {
        return isset(self::$_session[$itemName]);
    }

    /**
     * @param string $itemName
     * @param $value
     * @return void
     * setDataToSessionItem
     */
    final public static function setDataToSessionItem(string $itemName, $value):void
    {
        self::$_session[$itemName]  = $value;
    }

    /**
     * @param string $itemName
     * @return mixed|null
     * getDataBySessionItem
     */
    final public static function getDataBySessionItem(string $itemName)
    {
        return self::$_session[$itemName]??null;
    }

    /**
     * @param array $data
     * @return void
     * setDataToFiles
     */
    final public static function setDataToFiles(array $data):void
    {
        self::$_files               = $data;
    }

    /**
     * @return array
     * getDataByFiles
     */
    final public static function getDataByFiles():array
    {
        return self::$_files;
    }

    /**
     * @param string $itemName
     * @return bool
     * isDataByFilesItem
     */
    final public static function isDataByFilesItem(string $itemName):bool
    {
        return isset(self::$_files[$itemName]);
    }

    /**
     * @param string $itemName
     * @param $value
     * @return void
     * setDataToFilesItem
     */
    final public static function setDataToFilesItem(string $itemName, $value):void
    {
        self::$_files[$itemName]    = $value;
    }

    /**
     * @param string $itemName
     * @return mixed|null
     * getDataByFilesItem
     */
    final public static function getDataByFilesItem(string $itemName)
    {
        return self::$_files[$itemName]??null;
    }

    /**
     * @param array $data
     * @return void
     * setDataToServer
     */
    final public static function setDataToServer(array $data):void
    {
        self::$_server              = $data;
    }

    /**
     * @return array
     * getDataByServer
     */
    final public static function getDataByServer():array
    {
        return self::$_server;
    }

    /**
     * @param string $itemName
     * @return bool
     * isDataByServerItem
     */
    final public static function isDataByServerItem(string $itemName):bool
    {
        return isset(self::$_server[$itemName]);
    }

    /**
     * @param string $itemName
     * @param $value
     * @return void
     * setDataToServerItem
     */
    final public static function setDataToServerItem(string $itemName, $value):void
    {
        self::$_server[$itemName]   = $value;
    }

    /**
     * @param string $itemName
     * @return mixed|null
     * getDataByServerItem
     */
    final public static function getDataByServerItem(string $itemName)
    {
        return self::$_server[$itemName]??null;
    }

    /**
     * @param array $data
     * @return void
     * setDataToHeader
     */
    final public static function setDataToHeader(array $data):void
    {
        self::$_header              = $data;
    }

    /**
     * @return array
     * getDataByHeader
     */
    final public static function getDataByHeader():array
    {
        return self::$_header;
    }

    /**
     * @param string $itemName
     * @return bool
     * isDataByHeaderItem
     */
    final public static function isDataByHeaderItem(string $itemName):bool
    {
        $itemName   = Http::getHeaderName($itemName);
        return isset(self::$_header[$itemName]);
    }

    /**
     * @param string $itemName
     * @param $value
     * @return void
     * setDataToHeaderItem
     */
    final public static function setDataToHeaderItem(string $itemName, $value):void
    {
        $itemName   = Http::getHeaderName($itemName);
        self::$_header[$itemName]   = $value;
    }

    /**
     * @param string $itemName
     * @return mixed|null
     * getDataByHeaderItem
     */
    final public static function getDataByHeaderItem(string $itemName)
    {
        $itemName   = Http::getHeaderName($itemName);
        return self::$_header[$itemName]??null;
    }

    /**
     * @return int
     * getDataByRawType
     */
    final public static function getDataByRawType():int
    {
        return self::$_rawType;
    }

    /**
     * @return string
     * getDataByRawContent
     */
    final public static function getDataByRawContent():string
    {
        return self::$_rawContent;
    }

    /**
     * @param string $rawContent
     * @return void
     * setDataByRawContent
     */
    final public static function setDataByRawContent(string $rawContent):void
    {
        self::$_rawContent      = $rawContent;
    }

    /**
     * @param string $rootPath
     * @return void
     * setRootPath
     */
    final public static function setRootPath(string $rootPath):void
    {
        self::$rootPath      = $rootPath;
    }

    /**
     * @return string
     * getRootPath
     */
    final public static function getRootPath():string
    {
        return self::$rootPath;
    }

    /**
     * @param string $itemName
     * @return mixed|null
     * getByHeaderCookieItem
     */
    final public static function getByHeaderCookieItem(string $itemName)
    {
        $itemValue              = self::getDataByHeaderItem($itemName);
        if(is_null($itemValue)) $itemValue = self::getDataByCookieItem($itemName);
        return $itemValue;
    }

    /**
     * @param string $itemName
     * @param RouteConf $RouteConf
     * @return mixed|null
     * getByHeaderRouteItem
     */
    final public static function getByHeaderRouteItem(string $itemName, RouteConf $RouteConf)
    {
        $itemValue              = self::getDataByHeaderItem($itemName);
        if(is_null($itemValue) && $RouteConf->isReqHeaderFromCookie()){
            $itemValue          = self::getDataByCookieItem($itemName);
            if(is_null($itemValue)) $itemValue = self::getDataByCookieItem(strtolower($itemName));
        }
        if(is_null($itemValue) && $RouteConf->isReqHeaderFromGet()){
            $itemValue          = self::getDataByGetItem($itemName);
            if(is_null($itemValue)) $itemValue = self::getDataByGetItem(strtolower($itemName));
        }
        return $itemValue;
    }

    /**
     * @param string $itemName
     * @param array $orderList
     * @return mixed|null
     * getByHeaderOrderItem
     */
    public static function getByHeaderOrderItem(string $itemName, array $orderList = [self::KEY_SERVER, self::KEY_HEADER, self::KEY_COOKIE, self::KEY_POST, self::KEY_GET])
    {
        if(strlen($itemName) < 1 || count($orderList) < 1) return null;
        $itemValue              = null;
        foreach ($orderList as $orderType){
            if(!is_null($itemValue)) break;
            switch ($orderType){
                case self::KEY_SERVER:{
                    $itemValue  = self::getDataByServerItem($itemName);
                    break;
                }
                case self::KEY_HEADER:{
                    $itemValue  = self::getDataByHeaderItem($itemName);
                    break;
                }
                case self::KEY_COOKIE:{
                    $itemValue  = self::getDataByCookieItem($itemName);
                    if(is_null($itemValue)) $itemValue = self::getDataByCookieItem(strtolower($itemName));
                    break;
                }
                case self::KEY_POST:{
                    $itemValue  = self::getDataByPostItem($itemName);
                    if(is_null($itemValue)) $itemValue = self::getDataByPostItem(strtolower($itemName));
                    break;
                }
                case self::KEY_GET:{
                    $itemValue  = self::getDataByGetItem($itemName);
                    if(is_null($itemValue)) $itemValue = self::getDataByGetItem(strtolower($itemName));
                    break;
                }
            }
        }
        return $itemValue;
    }
}